package it.polimi.authentication.web.beans;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import it.polimi.TravelDream.BasePackageDTO;
import it.polimi.TravelDream.ExcursionDTO;
import it.polimi.TravelDream.FlightDTO;
import it.polimi.TravelDream.HotelDTO;
import it.polimi.TravelDream.SavedPackageDTO;
import it.polimi.TravelDream.PackageMgr;
import it.polimi.TravelDream.SearchEngine;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import com.sun.faces.util.MessageUtils;





@ManagedBean(name="packageBean")
@SessionScoped
public class PackageBean {
	
	@EJB
	private PackageMgr packageMgr;
	
    @EJB
	private SearchEngine searchEngine;

	private SavedPackageDTO savedPackage;
	
	private BasePackageDTO basePackage;
	
	private BasePackageDTO tempBasePackage;
	
	private HotelDTO selectedHotel;	
	private FlightDTO selectedFlight;
	private FlightDTO selectedRetFlight;
	private ExcursionDTO selectedExcursion;
	
	private boolean outFlight;
	private boolean retFlight;
	private boolean hotel;
 
	private String temp;

	private List<FlightDTO> filteredList;
	private List<FlightDTO> filteredRetList;
	private List<HotelDTO> filteredHotList;
	private List<ExcursionDTO> filteredExcList;
	private List<ExcursionDTO> selectedExcursionsList;
	
	private boolean renderFlight;
	private boolean renderRetFlight;
	private boolean renderHotel;
	private boolean renderExcursion;
	private boolean creationPage;

	public PackageBean(){
		selectedExcursionsList = new ArrayList<ExcursionDTO>();
		savedPackage = new SavedPackageDTO();
		basePackage = new BasePackageDTO();
		filteredList = new ArrayList<FlightDTO>();
		filteredList.clear();
		filteredRetList = new ArrayList<FlightDTO>();
		filteredRetList.clear();
		filteredHotList = new ArrayList<HotelDTO>();
		filteredHotList.clear();
		filteredExcList = new ArrayList<ExcursionDTO>();
		filteredExcList.clear();
		selectedFlight = new FlightDTO();
		selectedRetFlight = new FlightDTO();
		selectedHotel = new HotelDTO();

	}
	
	public String createBaseFromOutFlight(){
		basePackage = new BasePackageDTO();
		tempBasePackage = new BasePackageDTO();
		basePackage.setDepLocation(selectedFlight.getDepLocation());
		basePackage.setArrLocation(selectedFlight.getArrLocation());
		basePackage.setDepDate(selectedFlight.getDate_Time());
		basePackage.setOutFlightID(selectedFlight.getId());
		tempBasePackage.setDepDate(basePackage.getDepDate());
		tempBasePackage.setRetDate(basePackage.getRetDate());
		tempBasePackage.setArrLocation(basePackage.getArrLocation());
		tempBasePackage.setDepLocation(basePackage.getDepLocation());
		selectedExcursionsList.clear();
		creationPage=false;
		outFlight=true;
		hotel=false;
		retFlight=false;
		renderExcursion=false;
		renderFlight=false;
		renderHotel=false;
		renderRetFlight=false;
		return "/admins/PackageCreation?faces-redirect=true";
	}
	
	public String createBaseFromRetFlight(){
		basePackage = new BasePackageDTO();
		tempBasePackage = new BasePackageDTO();
		basePackage.setDepLocation(selectedRetFlight.getArrLocation());
		basePackage.setArrLocation(selectedRetFlight.getDepLocation());
		basePackage.setRetDate(selectedRetFlight.getDate_Time());
		basePackage.setRetFlightID(selectedRetFlight.getId());
		tempBasePackage.setDepDate(basePackage.getDepDate());
		tempBasePackage.setRetDate(basePackage.getRetDate());
		tempBasePackage.setArrLocation(basePackage.getArrLocation());
		tempBasePackage.setDepLocation(basePackage.getDepLocation());
		selectedExcursionsList.clear();
		outFlight=false;
		hotel=false;
		retFlight=true;
		creationPage=false;
		renderExcursion=false;
		renderFlight=false;
		renderHotel=false;
		renderRetFlight=false;
		return "/admins/PackageCreation?faces-redirect=true";
	}
	
	public String createBaseFromHotel(){
		basePackage = new BasePackageDTO();
		tempBasePackage = new BasePackageDTO();
		basePackage.setHotelID(selectedHotel.getId());
		basePackage.setArrLocation(selectedHotel.getCity());
		tempBasePackage.setArrLocation(basePackage.getArrLocation());
		selectedExcursionsList.clear();
		outFlight=false;
		hotel=true;
		retFlight=false;
		creationPage=false;
		renderExcursion=false;
		renderFlight=false;
		renderHotel=false;
		renderRetFlight=false;
		return "/admins/PackageCreation?faces-redirect=true";
	}
	
	public String createBaseFromExcursion(){
		basePackage = new BasePackageDTO();
		tempBasePackage = new BasePackageDTO();
		selectedExcursionsList.clear();
		basePackage.setArrLocation(selectedExcursion.getCity());
		tempBasePackage.setArrLocation(basePackage.getArrLocation());
		selectedExcursionsList.add(selectedExcursion);
		outFlight=false;
		hotel=false;
		retFlight=false;
		creationPage=false;
		renderExcursion=false;
		renderFlight=false;
		renderHotel=false;
		renderRetFlight=false;
		return "/admins/PackageCreation?faces-redirect=true";			
	}
	
	public String modifyPackage(){
		tempBasePackage = new BasePackageDTO();
		renderExcursion=false;
		renderFlight=false;
		renderHotel=false;
		renderRetFlight=false;
		tempBasePackage.setDepDate(basePackage.getDepDate());
		tempBasePackage.setRetDate(basePackage.getRetDate());
		tempBasePackage.setArrLocation(basePackage.getArrLocation());
		tempBasePackage.setDepLocation(basePackage.getDepLocation());
		if(basePackage.getOutFlightID()==-1){
			outFlight=false;
			selectedFlight=null;
		}
		else{
			outFlight=true;
			selectedFlight=searchEngine.searchFlightByID(basePackage.getOutFlightID());
		}
		if(basePackage.getRetFlightID()==-1){
			retFlight=false;
			selectedRetFlight=null;
		}
		else{
			retFlight=true;
			selectedRetFlight=searchEngine.searchFlightByID(basePackage.getRetFlightID());
		}
		if(basePackage.getHotelID()==-1){
			hotel=false;
			selectedHotel=null;
		}
		else{
			hotel=true;
			selectedHotel=searchEngine.searchHotelByID(basePackage.getHotelID());
		}
		selectedExcursionsList.clear();
		selectedExcursionsList=searchEngine.searchExcursionByBasePackageID(basePackage.getId());
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String insertBasePackage() {
		packageMgr.saveBasePackage(basePackage,selectedExcursionsList);
		return "/admins/home?faces-redirect=true";
	}
	
	public String modifyDepLoc(){
		tempBasePackage.setArrLocation(basePackage.getArrLocation());
		tempBasePackage.setDepDate(basePackage.getDepDate());
		tempBasePackage.setRetDate(basePackage.getRetDate());
		basePackage.setDepLocation(tempBasePackage.getDepLocation());
		if (selectedFlight!= null && selectedFlight.getDepLocation()!=null && !selectedFlight.getDepLocation().equals(basePackage.getDepLocation())){
			selectedFlight=null;
			outFlight=false;
			basePackage.setOutFlightID(-1);
		}
		if (selectedRetFlight!= null && selectedRetFlight.getArrLocation()!=null && !selectedRetFlight.getArrLocation().equals(basePackage.getDepLocation())){
			selectedRetFlight=null;
			retFlight=false;
			basePackage.setRetFlightID(-1);
		}
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
		
	}
	
	public String modifyArrLoc(){
		tempBasePackage.setDepLocation(basePackage.getDepLocation());
		tempBasePackage.setDepDate(basePackage.getDepDate());
		tempBasePackage.setRetDate(basePackage.getRetDate());
		basePackage.setArrLocation(tempBasePackage.getArrLocation());
		if (selectedFlight!= null && selectedFlight.getArrLocation()!=null && !selectedFlight.getArrLocation().equals(basePackage.getArrLocation())){
			selectedFlight=null;
			outFlight=false;
			basePackage.setOutFlightID(-1);
		}
		if (selectedRetFlight!= null && selectedRetFlight.getDepLocation()!=null && !selectedRetFlight.getDepLocation().equals(basePackage.getArrLocation())){
			selectedRetFlight=null;
			retFlight=false;
			basePackage.setRetFlightID(-1);
		}
		if(selectedHotel.getCity()!=null && !selectedHotel.getCity().equals(basePackage.getArrLocation())){
			selectedHotel=null;
			hotel= false;
			basePackage.setHotelID(-1);			
		}
		if(!selectedExcursionsList.isEmpty())
			if(!selectedExcursionsList.get(0).getCity().equals(basePackage.getArrLocation())){
			selectedExcursionsList.clear();				
			}
		
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
		
	}
	public String modifyDate(){
		
		if(basePackage.getRetDate()!=null&& tempBasePackage.getDepDate()!=null)
			{
				if (tempBasePackage.getDepDate().before(basePackage.getRetDate()))
					{
					tempBasePackage.setDepLocation(basePackage.getDepLocation());
					tempBasePackage.setArrLocation(basePackage.getArrLocation());
					tempBasePackage.setRetDate(basePackage.getRetDate());
					basePackage.setDepDate(tempBasePackage.getDepDate());
					if (selectedFlight!= null){
						selectedFlight=null;
						outFlight=false;
						basePackage.setOutFlightID(-1);
					}
					if(!selectedExcursionsList.isEmpty() &&  basePackage.getDepDate()!=null){
						for (Iterator<ExcursionDTO> it =selectedExcursionsList.iterator();it.hasNext();){
							ExcursionDTO excursionDTO = it.next();
							if (excursionDTO.getDate().before(basePackage.getDepDate()))	
								it.remove();					
					}}
					}
				else
				{tempBasePackage.setDepDate(basePackage.getDepDate());
				 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Warning", "The return date must be setted after the departure date"));  
				 if (creationPage==true) return "PackageModification?";
					else return "PackageCreation?";
				}
				}
		else 
			{
			tempBasePackage.setDepLocation(basePackage.getDepLocation());
			tempBasePackage.setArrLocation(basePackage.getArrLocation());
			tempBasePackage.setRetDate(basePackage.getRetDate());
			basePackage.setDepDate(tempBasePackage.getDepDate());
			if (selectedFlight!= null){
				selectedFlight=null;
				outFlight=false;
				basePackage.setOutFlightID(-1);
			}
			if(!selectedExcursionsList.isEmpty() &&  basePackage.getDepDate()!=null){
				for (Iterator<ExcursionDTO> it =selectedExcursionsList.iterator();it.hasNext();){
					ExcursionDTO excursionDTO = it.next();
					if (excursionDTO.getDate().before(basePackage.getDepDate()))	
						it.remove();					
			}}
			}
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";

		
	}
	
	public String modifyRetDate(){
		
		if(basePackage.getDepDate()!= null && tempBasePackage.getRetDate()!=null)
			{
				if(tempBasePackage.getRetDate().after(basePackage.getDepDate())){
				tempBasePackage.setDepLocation(basePackage.getDepLocation());
				tempBasePackage.setArrLocation(basePackage.getArrLocation());
				tempBasePackage.setDepDate(basePackage.getDepDate());
				basePackage.setRetDate(tempBasePackage.getRetDate());
				if (selectedRetFlight!= null){
					selectedRetFlight=null;
					retFlight=false;
					basePackage.setRetFlightID(-1);
				}
				if(!selectedExcursionsList.isEmpty() &&  basePackage.getRetDate()!=null){
					for (Iterator<ExcursionDTO> it =selectedExcursionsList.iterator();it.hasNext();){
						ExcursionDTO excursionDTO = it.next();
						if (excursionDTO.getDate().before(basePackage.getRetDate()))	
							it.remove();					
				}}
				}
				else {
					tempBasePackage.setRetDate(basePackage.getRetDate());
				 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Warning", "The return date must be setted after the departure date"));  
				 if (creationPage==true) return "PackageModification?";
					else return "PackageCreation?";
				}
			}
		else 
			{
			tempBasePackage.setDepLocation(basePackage.getDepLocation());
			tempBasePackage.setArrLocation(basePackage.getArrLocation());
			tempBasePackage.setDepDate(basePackage.getDepDate());
			basePackage.setRetDate(tempBasePackage.getRetDate());
			if (selectedRetFlight!= null){
				selectedRetFlight=null;
				retFlight=false;
				basePackage.setRetFlightID(-1);
			}
			if(!selectedExcursionsList.isEmpty() &&  basePackage.getRetDate()!=null){
				for (Iterator<ExcursionDTO> it =selectedExcursionsList.iterator();it.hasNext();){
					ExcursionDTO excursionDTO = it.next();
					if (excursionDTO.getDate().before(basePackage.getRetDate()))	
						it.remove();					
			}}
			}
		
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String searchOutFlight() {
		FlightDTO flight = new FlightDTO();
		flight.setDate_Time(basePackage.getDepDate());
		flight.setArrLocation(basePackage.getArrLocation());
		flight.setDepLocation(basePackage.getDepLocation());
		filteredList.clear();
		filteredList = searchEngine.searchFlightDTO(flight);
		if (basePackage.getRetDate()!=null)
			{
			for (Iterator<FlightDTO> it =filteredList.iterator();it.hasNext();){
				FlightDTO flightDTO = it.next();
				if (flightDTO.getDate_Time().after(basePackage.getRetDate()))	
					it.remove();
			}
		}	
		renderRetFlight=false;
		renderFlight=true;
		renderHotel=false;
		renderExcursion=false;
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String searchRetFlight() {
		FlightDTO flight = new FlightDTO();
		flight.setDate_Time(basePackage.getRetDate());
		flight.setArrLocation(basePackage.getDepLocation());
		flight.setDepLocation(basePackage.getArrLocation());
		filteredRetList.clear();
		filteredRetList = searchEngine.searchFlightDTO(flight);
		if (basePackage.getDepDate()!=null){
			for (Iterator<FlightDTO> it =filteredList.iterator();it.hasNext();){
				FlightDTO flightDTO = it.next();
				if (flightDTO.getDate_Time().before(basePackage.getDepDate()))	
					it.remove();		
			}
		}
		renderRetFlight=true;
		renderFlight=false;
		renderHotel=false;
		renderExcursion=false;
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String searchHotel() {
		HotelDTO hotel = new HotelDTO();
		hotel.setCity(basePackage.getArrLocation());
		filteredHotList.clear();
		filteredHotList = searchEngine.searchHotelDTO(hotel);
		renderRetFlight=false;
		renderFlight=false;
		renderHotel=true;
		renderExcursion=false;
		return "/admins/PackageCreation?faces-redirect=true";
	}
	
	public String searchExcursion() {
		ExcursionDTO excursion = new ExcursionDTO();
		excursion.setCity(basePackage.getArrLocation());
		excursion.setDate(basePackage.getDepDate());
		filteredExcList.clear();
		filteredExcList = searchEngine.searchExcursionDTO(excursion);
		renderRetFlight=false;
		renderFlight=false;
		renderHotel=false;
		renderExcursion=true;
		if (basePackage.getRetDate()!=null){
			for (Iterator<ExcursionDTO> it =filteredExcList.iterator();it.hasNext();){
				ExcursionDTO excursionDTO = it.next();
				if (excursionDTO.getDate().after(basePackage.getRetDate()))	
					it.remove();		
			}
		}
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String changeOutFlight() {
		basePackage.setOutFlightID(selectedFlight.getId());
		outFlight=true;
		filteredList.clear();
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String changeRetFlight() {
		basePackage.setRetFlightID(selectedRetFlight.getId());
		retFlight=true;
		filteredRetList.clear();
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String changeHotel() {
		basePackage.setHotelID(selectedHotel.getId());
		hotel=true;
		filteredHotList.clear();
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String addExcursion() {
		if (!selectedExcursionsList.contains(selectedExcursion))
		selectedExcursionsList.add(selectedExcursion);
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String removeOutFlight(){
		basePackage.setOutFlightID(-1);
		selectedFlight=null;
		outFlight=false;
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String removeRetFlight(){
		basePackage.setRetFlightID(-1);
		selectedRetFlight=null;
		retFlight=false;
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String removeHotel(){
		basePackage.setHotelID(-1);
		selectedHotel=null;
		hotel=false;
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String removeExcursion(){
		selectedExcursionsList.remove(selectedExcursion);
		if (creationPage==true) return "PackageModification?faces-redirect=true";
		else return "PackageCreation?faces-redirect=true";
	}
	
	public String updateBasepackage(){
		packageMgr.updateBasePackage(basePackage, selectedExcursionsList);
		return "/admins/home.xhtml";
	}

	public HotelDTO getSelectedHotel() {
		return selectedHotel;
	}

	public void setSelectedHotel(HotelDTO selectedHotel) {
		this.selectedHotel = selectedHotel;
	}

	public FlightDTO getSelectedFlight() {
		return selectedFlight;
	}

	public void setSelectedFlight(FlightDTO selectedFlight) {
		this.selectedFlight = selectedFlight;
	}

	public FlightDTO getSelectedRetFlight() {
		return selectedRetFlight;
	}

	public void setSelectedRetFlight(FlightDTO selectedRetFlight) {
		this.selectedRetFlight = selectedRetFlight;
	}

	public SavedPackageDTO getSavedPackage() {
		return savedPackage;
	}

	public void setSavedPackage(SavedPackageDTO savedPackage) {
		this.savedPackage = savedPackage;
	}

	public BasePackageDTO getBasePackage() {
		return basePackage;
	}

	public void setBasePackage(BasePackageDTO basePackage) {
		this.basePackage = basePackage;
	}

	public String getTemp() {
		return temp;
	}

	public void setTemp(String temp) {
		this.temp = temp;
	}

	public BasePackageDTO getTempBasePackage() {
		return tempBasePackage;
	}

	public void setTempBasePackage(BasePackageDTO tempBasePackage) {
		this.tempBasePackage = tempBasePackage;
	}

	public boolean isOutFlight() {
		return outFlight;
	}

	public void setOutFlight(boolean outFlight) {
		this.outFlight = !(this.outFlight);
	}

	public boolean isRetFlight() {
		return retFlight;
	}

	public void setRetFlight(boolean retFlight) {
		this.retFlight = retFlight;
	}

	public boolean isHotel() {
		return hotel;
	}

	public void setHotel(boolean hotel) {
		this.hotel = hotel;
	}
	
	public List<FlightDTO> getFilteredList() {
		return filteredList;
	}

	public void setFilteredList(List<FlightDTO> filteredList) {
		this.filteredList = filteredList;
	}

	public List<FlightDTO> getFilteredRetList() {
		return filteredRetList;
	}

	public void setFilteredRetList(List<FlightDTO> filteredRetList) {
		this.filteredRetList = filteredRetList;
	}

	public List<HotelDTO> getFilteredHotList() {
		return filteredHotList;
	}

	public void setFilteredHotList(List<HotelDTO> filteredHotList) {
		this.filteredHotList = filteredHotList;
	}

	public List<ExcursionDTO> getFilteredExcList() {
		return filteredExcList;
	}

	public void setFilteredExcList(List<ExcursionDTO> filteredExcList) {
		this.filteredExcList = filteredExcList;
	}

	public List<ExcursionDTO> getSelectedExcursionsList() {
		return selectedExcursionsList;
	}

	public void setSelectedExcursionsList(List<ExcursionDTO> selectedExcursionsList) {
		this.selectedExcursionsList = selectedExcursionsList;
	}

	public void setSelectedExcursion(ExcursionDTO selectedExcursion) {
		this.selectedExcursion = selectedExcursion;
	}

	public ExcursionDTO getSelectedExcursion() {
		return selectedExcursion;
	}

	public boolean isRenderFlight() {
		return renderFlight;
	}

	public void setRenderFlight(boolean renderFlight) {
		this.renderFlight = renderFlight;
	}

	public boolean isRenderRetFlight() {
		return renderRetFlight;
	}

	public void setRenderRetFlight(boolean renderRetFlight) {
		this.renderRetFlight = renderRetFlight;
	}

	public boolean isRenderHotel() {
		return renderHotel;
	}

	public void setRenderHotel(boolean renderHotel) {
		this.renderHotel = renderHotel;
	}

	public boolean isRenderExcursion() {
		return renderExcursion;
	}

	public void setRenderExcursion(boolean renderExcursion) {
		this.renderExcursion = renderExcursion;
	}

	public boolean isCreationPage() {
		return creationPage;
	}

	public void setCreationPage(boolean creationPage) {
		this.creationPage = creationPage;
	}
	
	
}
